using System;
using System.Collections.Generic;
using System.Drawing;

namespace Woz
{
    /// <summary>
    /// erase entity action used by the eraser tool to remove entities from the screen
    /// </summary>
    internal class EraseAction : Woz.Action
    {
        /// <summary>
        /// creates an instance of the erase entity action
        /// </summary>
        /// <param name="pEntities">the entities to erase from the screen</param>
        public EraseAction(params Woz.Entity[] pEntities)
        {
            // save the entities to remove
            this.mEntities = pEntities;

            // compute the bounding box of the entities to remove
            this.mBoundingRect = Woz.Entity.ComputeBoundingBox(this.mEntities);

            // inflate the bounding box by ten pixels
            this.mBoundingRect.Inflate(Woz.InkSpaceConverter.Instance.InkSpaceTenPixels,
                Woz.InkSpaceConverter.Instance.InkSpaceTenPixels);

            // inflate the bounding box by two more pixels
            this.mBoundingRect.Inflate(Woz.InkSpaceConverter.Instance.InkSpaceTwoPixels,
                Woz.InkSpaceConverter.Instance.InkSpaceTwoPixels);

            // make action string
            if (this.mEntities.Length == 1)
            {
                this.mActionString = String.Concat("Erased ", this.mEntities[0].ToString());
            }
            else
            {
                this.mActionString = String.Format("Erased {0} Entities", this.mEntities.Length);
            }
        }

        /// <summary>
        /// gets the name of the tool this action prefers
        /// </summary>
        public override string ToolName
        {
            get
            {
                return "Eraser";
            }
        }

        /// <summary>
        /// gets whether this action can be propagated or not
        /// </summary>
        public override bool Propagatable
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// removes the entities from the screen
        /// </summary>
        /// <param name="pScreen">the screen to erase the entity from</param>
        protected override void OnExecute(Woz.Screen pScreen)
        {
            // remove each of the entities from the screen
            foreach (Woz.Entity entity in this.mEntities)
            {
                pScreen.RemoveEntity(entity, false);
            }

            // now request the screen to update the bounding box
            Woz.ScreenManager.Instance.RequestSelectedScreenUpdate(pScreen, this.mBoundingRect);

            // also request the thumbnail to update
            Woz.ScreenManager.Instance.RequestSelectedScreenThumbnailUpdate(pScreen);
        }

        /// <summary>
        /// adds the entitis back to the screen
        /// </summary>
        /// <param name="pScreen">the screen to add entity back to</param>
        protected override void OnUnExecute(Woz.Screen pScreen)
        {
            // remove each of the entities from the screen
            foreach (Woz.Entity entity in this.mEntities)
            {
                pScreen.AddEntity(entity, false);
            }

            // now request the screen to update the bounding box
            Woz.ScreenManager.Instance.RequestSelectedScreenUpdate(pScreen, this.mBoundingRect);

            // also request the thumbnail to update
            Woz.ScreenManager.Instance.RequestSelectedScreenThumbnailUpdate(pScreen);
        }

        /// <summary>
        /// check to see if this action can be applied to the given screen
        /// </summary>
        /// <param name="pScreen">the screen to check</param>
        /// <returns>true if the action can be applied to the given screen</returns>
        public override bool CanApplyTo(Screen pScreen)
        {
            // make sure all entities are contained in this screen
            foreach (Woz.Entity entity in this.mEntities)
            {
                if (!pScreen.Contains(entity))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// the entities to remove
        /// </summary>
        private Woz.Entity[] mEntities;

        /// <summary>
        /// the bounding box of the entities to remove
        /// </summary>
        private Rectangle mBoundingRect;
    }
}
